package com.sun.showcase.thymeleaf;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractAttributeTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.util.StringUtils;
import org.thymeleaf.util.Validate;

import com.sun.showcase.pojo.SessionConstants;
import com.sun.showcase.utils.Authority;

public class SecurityProcessor extends AbstractAttributeTagProcessor {

	protected SecurityProcessor(String dialectPrefix,String attributeName,int precedence) {
		super(TemplateMode.HTML, // 处理thymeleaf 的模型
				dialectPrefix, // 标签前缀名
				null, // No tag name: match any tag name
				false, // No prefix to be applied to tag name
				attributeName, // 标签前缀的 属性 例如：< security:auth="">
				true, // Apply dialect prefix to attribute name
				precedence, // Precedence (inside dialect's precedence)
				true); // Remove the matched attribute afterwards
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void doProcess(ITemplateContext context, IProcessableElementTag tag, AttributeName attributeName,
			String attributeValue, IElementTagStructureHandler structureHandler) {
		final String rawValue = getRawValue(tag, attributeName); // 获取标签内容表达式
//		HttpSession httpSession = (HttpSession)context.getVariable("session");
//		Authority authentication = (Authority)httpSession.getAttribute(SessionConstants.KEY_AUTHENTICATION);
		Map<String,Object> map = (Map<String,Object>)context.getVariable("session");
		Authority authentication =  (Authority)map.get(SessionConstants.KEY_AUTHENTICATION);
		if(authentication == null){
			structureHandler.removeBody();
		}
		if(hasAuth(authentication,rawValue)){
			return;
		}
		structureHandler.removeBody();
		
	}
	
    public static String getRawValue(final IProcessableElementTag element, final AttributeName attributeName) {  
    	Validate.notNull(element, "element must not be null");  
    	Validate.notNull(attributeName, "attributeName must not be empty");  
  
        final String rawValue = StringUtils.trim(element.getAttributeValue(attributeName));  
        Validate. notEmpty(rawValue, "value of '" + attributeName + "' must not be empty");  
  
        return rawValue;  
    }  
	public String getRawValue(final IProcessableElementTag element, final String attributeName) {
		Validate.notNull(element, "element must not be null");
		Validate.notEmpty(attributeName, "attributeName must not be empty");

		final String rawValue = StringUtils.trim(element.getAttributeValue(attributeName));
		Validate.notEmpty(rawValue, "value of '" + attributeName + "' must not be empty");

		return rawValue;
	}
	private Set<String> codesSet(String code){
		String[] codes = code.split(",");
		return new HashSet<String>(Arrays.asList(codes));
	}
	private boolean hasAuth(Authority authentication,String code){
		Set<String> authCodeSet  = this.codesSet(code);
		for(String auth: authCodeSet){
			if(authentication.getComponentResources().contains(auth)){
				return true;
			}
		}
		return false;
	}
}
